package com.gqh.weather.util;

import com.gqh.weather.config.MinioConfig;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.GetObjectArgs;
import io.minio.Result;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

/**
 * MinIO工具类
 */
@Slf4j
@Component
public class MinioUtil {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;

    /**
     * 保存上传的文件并返回URL
     *
     * @param file 上传的文件
     * @param bucket 存储桶名称
     * @param directory 目录路径
     * @return 文件URL
     * @throws IOException IO异常
     */
    public String saveUploadFile(MultipartFile file, String bucket, String directory) throws IOException {
        try {
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf(".")) : "";
            String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;

            // 确保存储桶存在
            String objectName = fileName;
            if (directory != null && !directory.isEmpty()) {
                objectName = directory + "/" + fileName;
                if (!objectName.startsWith("/")) {
                    objectName = "/" + objectName;
                }
            }

            // 使用MinIO上传文件
            try (InputStream inputStream = file.getInputStream()) {
                minioClient.putObject(
                    PutObjectArgs.builder()
                        .bucket(bucket)
                        .object(objectName)
                        .stream(inputStream, file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build()
                );
            }

            // 返回文件访问URL
            return "/files/" + bucket + (objectName.startsWith("/") ? objectName : "/" + objectName);
        } catch (Exception e) {
            log.error("文件上传到MinIO失败", e);
            throw new IOException("文件上传失败", e);
        }
    }

    /**
     * 保存上传的文件并返回URL（不指定目录）
     *
     * @param file 上传的文件
     * @param bucket 存储桶名称
     * @return 文件URL
     * @throws IOException IO异常
     */
    public String saveUploadFile(MultipartFile file, String bucket) throws IOException {
        return saveUploadFile(file, bucket, null);
    }

    /**
     * 保存上传的文件并返回URL（使用默认存储桶和目录）
     *
     * @param file 上传的文件
     * @return 文件URL
     * @throws IOException IO异常
     */
    public String saveUploadFile(MultipartFile file) throws IOException {
        return saveUploadFile(file, minioConfig.getBucketStudentFace(), "student_faces");
    }

    /**
     * 保存图片文件并返回URL
     *
     * @param file 上传的图片文件
     * @return 文件URL
     * @throws IOException IO异常
     */
    public String savePictureFile(MultipartFile file) throws IOException {
        return saveUploadFile(file, minioConfig.getBucketStudentFace(), "pictures");
    }

    /**
     * 保存Excel文件并返回URL
     *
     * @param file 上传的Excel文件
     * @return 文件URL
     * @throws IOException IO异常
     */
    public String saveExcelFile(MultipartFile file) throws IOException {
        return saveUploadFile(file, minioConfig.getBucketStudentFace(), "excels");
    }

    /**
     * 保存PDF文件并返回URL
     *
     * @param file 上传的PDF文件
     * @return 文件URL
     * @throws IOException IO异常
     */
    public String savePdfFile(MultipartFile file) throws IOException {
        return saveUploadFile(file, minioConfig.getBucketStudentFace(), "pdfs");
    }

    /**
     * 从MinIO获取文件的InputStream
     *
     * @param bucket 存储桶名称
     * @param objectName 对象名称
     * @return 文件的InputStream
     * @throws IOException IO异常
     */
    public InputStream getFileInputStream(String bucket, String objectName) throws IOException {
        try {
            return minioClient.getObject(
                GetObjectArgs.builder()
                    .bucket(bucket)
                    .object(objectName)
                    .build()
            );
        } catch (Exception e) {
            log.error("从MinIO获取文件失败", e);
            throw new IOException("获取文件失败", e);
        }
    }

    /**
     * 从MinIO获取文件的InputStream（使用默认存储桶）
     *
     * @param objectName 对象名称
     * @return 文件的InputStream
     * @throws IOException IO异常
     */
    public InputStream getFileInputStream(String objectName) throws IOException {
        return getFileInputStream(minioConfig.getBucketStudentFace(), objectName);
    }
}